//
//  NSString+Extension.m
//  ChatForHot
//
//  Created by wr on 2018/10/9.
//  Copyright © 2018年 FLY. All rights reserved.
//

#import "NSString+Extension.h"
#import <CommonCrypto/CommonHMAC.h>

@implementation NSString (Extension)

+ (BOOL)isEmpty:(NSString *)string {
  return !string.isNotBlank;
}

- (BOOL)isNotBlank {
  NSCharacterSet *blank = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  for (NSInteger i = 0; i < self.length; ++i) {
    unichar c = [self characterAtIndex:i];
    if (![blank characterIsMember:c]) {
      return YES;
    }
  }
  return NO;
}

- (NSString*)substringFrom:(NSInteger)from to:(NSInteger)to {
  NSRange r;
  r.location = from;
  r.length = to - from;
  return [self substringWithRange:r];
}

- (NSInteger)indexOf:(NSString*)string from:(NSInteger)from {
  NSRange r;
  r.location = from;
  r.length = [self length] - r.location;
  
  NSRange index = [self rangeOfString:string options:NSLiteralSearch range:r];
  if (index.location == NSNotFound) {
    return -1;
  }
  return index.location + index.length;
}

- (BOOL)startsWith:(NSString*)string {
  if([self length] < [string length]) return NO;
  return [string isEqualToString:[self substringFrom:0 to:[string length]]];
}

- (BOOL)containsString:(NSString *)string {
  NSRange range = [[self lowercaseString] rangeOfString:[string lowercaseString]];
  return range.location != NSNotFound;
}
- (NSString *)HOTCHATTotalStringUrl {
    return [NSString stringWithFormat:@"%@%@",APIHEADER,self];
}

- (NSString *)HOTCHATmaxLength:(NSInteger)maxLen{
    if (self.length > maxLen) {
        return [self substringToIndex:maxLen];
    }
    return self;
}

- (NSInteger)HOTCHATleftCharWithmaxLength:(NSInteger)maxLen {
    return (maxLen - self.length);
}
//get vip img

- (NSString *)HOTCHATgetVipStr{

    if ([self isEqualToString:@"1001"]) {

        return @"all_ic_writevip";
        
    }else if ([self isEqualToString:@"1002"]){

        return @"all_ic_diamondsvip";
    }else if ([self isEqualToString:@"1003"] || [self isEqualToString:@"9999"]){

        return @"all_ic_vip";
    }
    return @"";
}
@end

@implementation NSString (Transform)

- (NSString *)md5 {
  const char *cStr = [self UTF8String];
  unsigned char result[16];
  CC_MD5( cStr, (unsigned int) strlen(cStr), result);
  return [NSString stringWithFormat:
          @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
          result[0], result[1], result[2], result[3],
          result[4], result[5], result[6], result[7],
          result[8], result[9], result[10], result[11],
          result[12], result[13], result[14], result[15]
          ];
}

static char base64EncodingTable[64] = {
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};

- (NSString *)base64 {
  if (self.isNotBlank == NO) {
    return @"";
  }
  NSData * data = [self dataUsingEncoding:NSUTF8StringEncoding];
  NSInteger length = data.length;
  
  unsigned long ixtext, lentext;
  long ctremaining;
  unsigned char input[3], output[4];
  short i, charsonline = 0, ctcopy;
  const unsigned char *raw;
  NSMutableString *result;
  
  lentext = [data length];
  if (lentext < 1)
    return @"";
  result = [NSMutableString stringWithCapacity: lentext];
  raw = [data bytes];
  ixtext = 0;
  
  while (true) {
    ctremaining = lentext - ixtext;
    if (ctremaining <= 0)
      break;
    for (i = 0; i < 3; i++) {
      unsigned long ix = ixtext + i;
      if (ix < lentext)
        input[i] = raw[ix];
      else
        input[i] = 0;
    }
    output[0] = (input[0] & 0xFC) >> 2;
    output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
    output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
    output[3] = input[2] & 0x3F;
    ctcopy = 4;
    switch (ctremaining) {
      case 1:
        ctcopy = 2;
        break;
      case 2:
        ctcopy = 3;
        break;
    }
    
    for (i = 0; i < ctcopy; i++)
      [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
    
    for (i = ctcopy; i < 4; i++)
      [result appendString: @"="];
    
    ixtext += 3;
    charsonline += 4;
    
    if ((length > 0) && (charsonline >= length))
      charsonline = 0;
  }
  return result;
}

+ (NSString*)uniqueString {
  CFUUIDRef  uuidObj = CFUUIDCreate(nil);
  NSString  *uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(nil, uuidObj);
  CFRelease(uuidObj);
  return uuidString;
}

- (NSString *)urlEncodedString {
  if ([self respondsToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) {
    /**
     AFNetworking/AFURLRequestSerialization.m
     
     Returns a percent-escaped string following RFC 3986 for a query string key or value.
     RFC 3986 states that the following characters are "reserved" characters.
     - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
     - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
     In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
     query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
     should be percent-escaped in the query string.
     - parameter string: The string to be percent-escaped.
     - returns: The percent-escaped string.
     */
    static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
    static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
    
    NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
    [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];
    static NSUInteger const batchSize = 50;
    
    NSUInteger index = 0;
    NSMutableString *escaped = @"".mutableCopy;
    
    while (index < self.length) {
      NSUInteger length = MIN(self.length - index, batchSize);
      NSRange range = NSMakeRange(index, length);
      // To avoid breaking up character sequences such as 👴🏻👮🏽
      range = [self rangeOfComposedCharacterSequencesForRange:range];
      NSString *substring = [self substringWithRange:range];
      NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
      [escaped appendString:encoded];
      
      index += range.length;
    }
    return escaped;
  } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding);
    NSString *encoded = (__bridge_transfer NSString *)
    CFURLCreateStringByAddingPercentEscapes(
                                            kCFAllocatorDefault,
                                            (__bridge CFStringRef)self,
                                            NULL,
                                            CFSTR("!#$&'()*+,/:;=?@[]"),
                                            cfEncoding);
    return encoded;
#pragma clang diagnostic pop
  }
}

- (NSString *)urlDecodedString {
  if ([self respondsToSelector:@selector(stringByRemovingPercentEncoding)]) {
    return [self stringByRemovingPercentEncoding];
  } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    CFStringEncoding en = CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding);
    NSString *decoded = [self stringByReplacingOccurrencesOfString:@"+"
                                                        withString:@" "];
    decoded = (__bridge_transfer NSString *)
    CFURLCreateStringByReplacingPercentEscapesUsingEncoding(
                                                            NULL,
                                                            (__bridge CFStringRef)decoded,
                                                            CFSTR(""),
                                                            en);
    return decoded;
#pragma clang diagnostic pop
  }
}

+ (NSString *)convertDataToHexStr:(NSData *)data {
  if (!data || [data length] == 0) {
    return @"";
  }
  NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
  
  [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
    unsigned char *dataBytes = (unsigned char*)bytes;
    for (NSInteger i = 0; i < byteRange.length; i++) {
      NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
      if ([hexStr length] == 2) {
        [string appendString:hexStr];
      } else {
        [string appendFormat:@"0%@", hexStr];
      }
    }
  }];
  
  string = [NSMutableString stringWithString:[string uppercaseString]];
  
  if (string.length < 12) {
    return @"";
  }
  
  NSString *disposeString = @"";
  
  for (NSInteger i = 0; i< string.length/2; i++) {
    if (i != 0) {
      disposeString = [disposeString stringByAppendingString:@":"];
    }
    disposeString = [disposeString stringByAppendingString:[string substringWithRange:NSMakeRange(i*2,2)]];
  }
  
  return disposeString;
}

- (NSString *)removeMagicalChar {
  if (self.length == 0) {
    return self;
  }
  
  NSError *error = nil;
  NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\u0300-\u036F]" options:NSRegularExpressionCaseInsensitive error:&error];
  NSString *modifiedString = [regex stringByReplacingMatchesInString:self options:NSMatchingReportProgress range:NSMakeRange(0, self.length) withTemplate:@""];
  return modifiedString;
}

- (NSUInteger)lengthWhenCountingNonASCIICharacterAsTwo {
  NSUInteger characterLength = 0;
  NSStringEncoding encod = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  char *p = (char *)[self cStringUsingEncoding:encod];
  for (NSInteger i = 0, l = [self lengthOfBytesUsingEncoding:encod]; i < l; i++) {
    if (*p) {
      characterLength++;
    }
    p++;
  }
  return characterLength;
}

- (NSString *)substringAvoidBreakingUpCharacterSequencesToIndex:(NSUInteger)index
                                                      lessValue:(BOOL)lessValue
                                 countingNonASCIICharacterAsTwo:(BOOL)countingNonASCIICharacterAsTwo {
  index = countingNonASCIICharacterAsTwo ? [self transformIndexToDefaultModeWithIndex:index] : index;
  NSRange range = [self rangeOfComposedCharacterSequenceAtIndex:index];
  return [self substringToIndex:lessValue ? range.location : NSMaxRange(range)];
}

- (NSUInteger)transformIndexToDefaultModeWithIndex:(NSUInteger)index {
  CGFloat strlength = 0.f;
  NSInteger i = 0;
  for (i = 0; i < self.length; i++) {
    unichar character = [self characterAtIndex:i];
    if (isascii(character)) {
      strlength += 1;
    } else {
      strlength += 2;
    }
    if (strlength >= index + 1) return i;
  }
  return 0;
}
@end

@implementation NSString (Trim)

- (NSString *)trim {
  return [self stringByTrim];
}

- (NSString *)stringByTrim {
  return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)trimSpaceAndEnter{
  return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (void)trimSpaceAndEnterAtTheEnd:(NSMutableString *)text {
  NSString *temp = nil;
  
  if (self.length == 0) {
    return;
  }
  
  NSInteger index = text.length - 1;
  NSRange range = NSMakeRange(index,1);
  temp = [text substringWithRange:range];
  if ([temp isEqualToString:@""] || [temp isEqualToString:@" "] || [temp isEqualToString:@"\r"] || [temp isEqualToString:@"\n"]) {
    [text deleteCharactersInRange:range];
    [self trimSpaceAndEnterAtTheEnd:text];
  }
}
@end

@implementation NSString (Layout)

- (CGSize)sizeForFont:(UIFont *)font size:(CGSize)size mode:(NSLineBreakMode)lineBreakMode {
  CGSize result;
  if (!font) font = [UIFont systemFontOfSize:12];
  if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
    NSMutableDictionary *attr = [NSMutableDictionary new];
    attr[NSFontAttributeName] = font;
    if (lineBreakMode != NSLineBreakByWordWrapping) {
      NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
      paragraphStyle.lineBreakMode = lineBreakMode;
      attr[NSParagraphStyleAttributeName] = paragraphStyle;
    }
    CGRect rect = [self boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                  attributes:attr context:nil];
    result = rect.size;
  } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    result = [self sizeWithFont:font constrainedToSize:size lineBreakMode:lineBreakMode];
#pragma clang diagnostic pop
  }
  return result;
}

- (CGFloat)widthForFont:(UIFont *)font {
  CGSize size = [self sizeForFont:font size:CGSizeMake(HUGE, HUGE) mode:NSLineBreakByWordWrapping];
  return size.width;
}

- (CGFloat)heightForFont:(UIFont *)font width:(CGFloat)width {
  CGSize size = [self sizeForFont:font size:CGSizeMake(width, HUGE) mode:NSLineBreakByWordWrapping];
  return size.height;
}
@end
